package com.beta.cat.utils.thread;

import java.util.concurrent.*;

/**
 * @Auther: pcc
 * @Date: 2024/1/11 15:56
 * @Description:
 */
public class ThreadsManager {

    private static volatile ThreadPoolExecutor threadPool;

    /**
     * cpu型线程池创建
     * 基于服务创建一个线程默认最优配置参数，创建多个线程池需自行计算使用带参数的线程池创建方法
     * 适合cpu占用执行时间较多的场景
     * @return
     */
    public static ThreadPoolExecutor getCPUInstance() {
        int numProcessors = Runtime.getRuntime().availableProcessors();
        return getInstance(numProcessors, numProcessors);
    }

    /**
     * IO型线程池创建
     * 基于服务创建一个线程池默认最优配置参数，创建多个线程池需自行计算使用带参数的线程池创建方法
     * 适合IO占用执行时间较多的场景,如：文件读取操作等
     * @return
     */
    public static ThreadPoolExecutor getIOInstance() {
        int numProcessors = Runtime.getRuntime().availableProcessors();
        return getInstance(2 * numProcessors, 2 * numProcessors);
    }

    /**
     * 单例 双重校验机制创建线程池
     * @param coreThreads
     * @param maxThreads
     * @return
     */
    public static ThreadPoolExecutor getInstance(Integer coreThreads, Integer maxThreads) {
        if (threadPool == null) {
            synchronized (ThreadsManager.class) {
                if (threadPool == null) {
                    // 创建线程池
                    threadPool = new ThreadPoolExecutor(coreThreads, maxThreads, 0L,
                            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), r -> {
                        Thread t = new Thread(r);
                        t.setName("ThreadsManager-Instance");
                        t.setDaemon(true);
                        return t;
                    });
                }
            }
        }
        return threadPool;
    }

    /**
     * cpu型线程池创建，该模式谨慎使用在方法中，在类中全局使用
     * 基于服务创建一个线程池默认最优配置参数，创建多个线程池需自行计算使用带参数的线程池创建方法
     * 适合cpu占用执行时间较多的场景
     * @return
     */
    public static ThreadPoolExecutor getCPUThreadPool() {
        int numProcessors = Runtime.getRuntime().availableProcessors();
        return getThreadPool(numProcessors, numProcessors);
    }

    /**
     * IO型线程池创建，该模式谨慎使用在方法中，在类中全局使用
     * 基于服务创建一个线程池默认最优配置参数，创建多个线程池需自行计算使用带参数的线程池创建方法
     * 适合IO占用执行时间较多的场景,如：文件读取操作等
     * @return
     */
    public static ThreadPoolExecutor getIOThreadPool() {
        int numProcessors = Runtime.getRuntime().availableProcessors();
        return getThreadPool(2 * numProcessors, 2 * numProcessors);
    }

    /**
     * 该模式谨慎使用在方法中，在类中全局使用
     * 方法中请使用单例模式
     * @param coreThreads
     * @param maxThreads
     * @return
     */
    public static ThreadPoolExecutor getThreadPool(Integer coreThreads, Integer maxThreads){
        return new ThreadPoolExecutor(coreThreads, maxThreads, 0L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue <>(1024), r -> {
            Thread t = new Thread(r);
            t.setName("ThreadsManager-pool");
            t.setDaemon(true);
            return t;
        });
    }


}
